/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package tal.drivechain.chain.shell;

import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.ClipboardOwner;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import tal.drivechain.chain.AbortChainException;
import tal.drivechain.chain.Chain;
import tal.drivechain.chain.ChainNode;
import tal.drivechain.chain.FreePatcher;
import tal.drivechain.chain.script.ScriptCommand;
import tal.drivechain.chain.script.ScriptCompiler;
import tal.drivechain.parsing.Tokenizer;
import tal.drivechain.plugin.Module;

/**
 *
 * @author Tal Eisenberg
 */
public class CopyPasteCommand extends ShellCommand {
    private CopyPasteMachine machine = new CopyPasteMachine();

    public CopyPasteCommand(DriveShell shell) { super(shell); }

    @Override
    public boolean runCommand(ScriptCommand command) throws IllegalArgumentException {
        if (command.getName().equals("copy")) {
            machine.copy(namesToScript(command));
            out.println("Nodes copied to clipboard.");
            return true;
        } else if (command.getName().equals("paste")) {
            paste();
            return true;
        } else if (command.getName().equals("duplicate")) {
            machine.copy(namesToScript(command));
            paste();
            return true;
        } else return false;
    }

    @Override
    public String[] getCommands() {
        return new String[] { "copy", "paste", "duplicate" };
    }

    public void paste() {
        ScriptCompiler c = new ScriptCompiler();
        c.suppressConnectionErrors(true);
        try {
            Chain chain = c.compileChain("pasted", null, new FreePatcher(), machine.getContents());
            for (ChainNode n : chain.getChildNodes().values()) {
                int idx = 2;
                String baseName = n.getName();
                while (shell.getActiveChain().getChildNodes().containsKey(n.getName())) { // goes in if needs to change node name
                    n.setName(baseName+idx);
                    idx++;
                }
                shell.getActiveChain().addChild(n);
            }
        } catch (AbortChainException ex) {
            throw new IllegalArgumentException(ex.getMessage());
        }
    }

    private List<ChainNode> namesToScript(ScriptCommand command) {
            Tokenizer t = new Tokenizer(command.getArg1()+command.getArg2(), ',');
            List<ChainNode> nodesToCopy = new ArrayList<ChainNode>();
            for (String name : t.getTokens()) {
                nodesToCopy.add(shell.getActiveChain().getNodeByPath(name));
            }
            return nodesToCopy;

    }

    class CopyPasteMachine implements ClipboardOwner {
        Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();

        public void lostOwnership(Clipboard clpbrd, Transferable t) {}

        public void copy(List<ChainNode> nodesToCopy) {
            String clip = "";
            for (ChainNode n : nodesToCopy)
                clip += n.generateScript() + "\n\n";

/*            if (nodesToCopy.size()>1 || nodesToCopy.get(0) instanceof Module) {
                clip = "chain copies {\n\t" + clip.replaceAll("\\\n", "\n\t").trim() + "\n};";
            }*/
            clipboard.setContents(new StringSelection(clip), this);
        }

        public String getContents() {
            String result = null;

            Transferable contents = clipboard.getContents(null);
            boolean hasTransferableText = (contents != null) && contents.isDataFlavorSupported(DataFlavor.stringFlavor);

            if ( hasTransferableText ) {
                try {
                    result = (String)contents.getTransferData(DataFlavor.stringFlavor);
                } catch (UnsupportedFlavorException ex){
                    //highly unlikely since we are using a standard DataFlavor
                    System.out.println(ex);
                    ex.printStackTrace();
                } catch (IOException ex) {
                    System.out.println(ex);
                    ex.printStackTrace();
                }
            }
            return result;
        }
    }
}
